---
id: formats
title: Camera Formats
sidebar_label: Camera Formats
---

import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
import useBaseUrl from '@docusaurus/useBaseUrl'

<div class="image-container">
  <img width="283" src={useBaseUrl("img/example.png")} />
</div>

## What are camera formats?

Each camera device (see ["Camera Devices"](devices)) provides a number of formats that have different specifications.
There are formats specifically designed for high-resolution photo capture (but lower FPS), or formats that are designed for slow-motion video capture which have frame-rates of up to 240 FPS (but lower resolution).

## What if I don't want to choose a format?

If you don't want to specify a Camera Format, you don't have to. The Camera automatically chooses the best matching format for the current camera device. This is why the Camera's `format` property is _optional_.

**🚀 Continue with: [Taking Photos](./taking-photos)**

## Choosing custom formats

To understand a bit more about camera formats, you first need to understand a few "general camera basics":

* Each camera device is built differently, e.g. front-facing Cameras often don't have resolutions as high as the Cameras on the back. (see ["Camera Devices"](devices))
* Formats are designed for specific use-cases, here are some examples for formats on a Camera Device:
  * 4k Photos, 4k Videos, 30 FPS (high quality)
  * 4k Photos, 1080p Videos, 60 FPS (high FPS)
  * 4k Photos, 1080p Videos, 240 FPS (ultra high FPS/slow motion)
  * 720p Photos, 720p Videos, 30 FPS (smaller buffers/e.g. faster face detection)
* Each app has different requirements, so the format filtering is up to you.
* The `videoResolution` and `videoAspectRatio` options also affect the preview, as preview is also running in the video stream.

To get all available formats, simply use the `CameraDevice`'s [`formats` property](/docs/api/interfaces/CameraDevice#formats).  These are a [CameraFormat's](/docs/api/interfaces/CameraDeviceFormat) props:

- [`photoHeight`](/docs/api/interfaces/CameraDeviceFormat#photoheight)/[`photoWidth`](/docs/api/interfaces/CameraDeviceFormat#photoWidth): The resolution that will be used for taking photos. Choose a format with your desired resolution.
- [`videoHeight`](/docs/api/interfaces/CameraDeviceFormat#videoheight)/[`videoWidth`](/docs/api/interfaces/CameraDeviceFormat#videoWidth): The resolution that will be used for recording videos and streaming into frame processors. This also affects the preview's aspect ratio. Choose a format with your desired resolution.
- [`minFps`](/docs/api/interfaces/CameraDeviceFormat#minfps)/[`maxFps`](/docs/api/interfaces/CameraDeviceFormat#maxfps): A range of possible values for the `fps` property. For example, if your format has `minFps: 1` and `maxFps: 60`, you can either use `fps={30}`, `fps={60}` or any other value in between for recording videos and streaming into frame processors.
- [`videoStabilizationModes`](/docs/api/interfaces/CameraDeviceFormat#videostabilizationmodes): All supported Video Stabilization Modes, digital and optical. If this specific format contains your desired [`VideoStabilizationMode`](/docs/api/#videostabilizationmode), you can pass it to your `<Camera>` via the [`videoStabilizationMode` property](/docs/api/interfaces/CameraProps#videoStabilizationMode).
- [`supportsVideoHdr`](/docs/api/interfaces/CameraDeviceFormat#supportsvideohdr): Whether this specific format supports true 10-bit HDR for video capture. If this is `true`, you can enable `videoHdr` on your `<Camera>`.
- [`supportsPhotoHdr`](/docs/api/interfaces/CameraDeviceFormat#supportsphotohdr): Whether this specific format supports HDR for photo capture. It will use multiple captures to fuse over-exposed and under-exposed Images together to form one HDR photo. If this is `true`, you can enable `photoHdr` on your `<Camera>`.
- [`supportsDepthCapture`](/docs/api/interfaces/CameraDeviceFormat#supportsdepthcapture): Whether this specific format supports depth data capture. For devices like the TrueDepth/LiDAR cameras, this will always be true.
- ...and more. See the [`CameraDeviceFormat` type](/docs/api/interfaces/CameraDeviceFormat) for all supported properties.

You can either find a matching format manually by looping through your `CameraDevice`'s [`formats` property](/docs/api/interfaces/CameraDevice#formats), or by using the helper functions from VisionCamera:

<Tabs
  groupId="component-style"
  defaultValue="hooks"
  values={[
    {label: 'Hooks API', value: 'hooks'},
    {label: 'Imperative API', value: 'imperative'}
  ]}>
<TabItem value="hooks">

```ts
const device = ...
const format = useCameraFormat(device, [
  { videoAspectRatio: 16 / 9 },
  { videoResolution: { width: 3048, height: 2160 } },
  { fps: 60 }
])
```

</TabItem>
<TabItem value="imperative">

```ts
const device = ...
const format = getCameraFormat(device, [
  { videoAspectRatio: 16 / 9 },
  { videoResolution: { width: 3048, height: 2160 } },
  { fps: 60 }
])
```

</TabItem>
</Tabs>

The **filter is ordered by priority (descending)**, so if there is no format that supports both 4k and 60 FPS, the function will prefer 4k@30FPS formats over 1080p@60FPS formats, because 4k is a more important requirement than 60 FPS.

If you want to record slow-motion videos, you want a format with a really high FPS setting, for example:

<Tabs
  groupId="component-style"
  defaultValue="hooks"
  values={[
    {label: 'Hooks API', value: 'hooks'},
    {label: 'Imperative API', value: 'imperative'}
  ]}>
<TabItem value="hooks">

```ts
const device = ...
const format = useCameraFormat(device, [
  { fps: 240 }
])
```

</TabItem>
<TabItem value="imperative">

```ts
const device = ...
const format = getCameraFormat(device, [
  { fps: 240 }
])
```

</TabItem>
</Tabs>

If there is no format that has exactly 240 FPS, the closest thing to it will be used.

You can also use the `'max'` flag to just use the maximum available resolution:

<Tabs
  groupId="component-style"
  defaultValue="hooks"
  values={[
    {label: 'Hooks API', value: 'hooks'},
    {label: 'Imperative API', value: 'imperative'}
  ]}>
<TabItem value="hooks">

```ts
const device = ...
const format = useCameraFormat(device, [
  { videoResolution: 'max' },
  { photoResolution: 'max' }
])
```

</TabItem>
<TabItem value="imperative">

```ts
const device = ...
const format = getCameraFormat(device, [
  { videoResolution: 'max' },
  { photoResolution: 'max' }
])
```

</TabItem>
</Tabs>

### Templates

For common use-cases, VisionCamera also exposes pre-defined Format templates:

<Tabs
  groupId="component-style"
  defaultValue="hooks"
  values={[
    {label: 'Hooks API', value: 'hooks'},
    {label: 'Imperative API', value: 'imperative'}
  ]}>
<TabItem value="hooks">

```ts
const device = ...
const format = useCameraFormat(device, Templates.Snapchat)
```

</TabItem>
<TabItem value="imperative">

```ts
const device = ...
const format = getCameraFormat(device, Templates.Snapchat)
```

</TabItem>
</Tabs>

## Camera Props

The `Camera` View provides a few props that depend on the specified `format`.

### FPS

For example, a camera device might have a 1080p and a 4k format, but the 4k one can only stream at 60 FPS, while the 1080p format can do 240 FPS.

To find a 240 FPS format we can use the [`useCameraFormat(..)`](/docs/api#usecameraformat) hook to find a suitable format, then pass it's maximum supported FPS as the Camera's target FPS:

```tsx
function App() {
  const device = ...
  const format = useCameraFormat(device, [
    { fps: 240 }
  ])
  const fps = format.maxFps // <-- 240 FPS, or lower if 240 FPS is not available

  return (
    <Camera
      style={StyleSheet.absoluteFill}
      device={device}
      format={format}
      fps={fps}
    />
  )
}
```

Setting [`fps`](/docs/api/interfaces/CameraProps#fps) to a single number will configure the Camera to use a fixed FPS rate.

Under low/dark lighting conditions, a Camera could throttle it's FPS rate to receive more light, which would result in **higher quality and better exposed photos and videos**.
VisionCamera provides an API to set a variable FPS rate, which internally automatically adjusts FPS rate depending on lighting conditions.
To use this, simply set [`fps`](/docs/api/interfaces/CameraProps#fps) to a tuple (`[min, max]`).

For example, we could target 30 FPS, but allow the Camera to throttle down to 20 FPS under low lighting conditions:

```tsx
function App() {
  // ...
  const format = ...
  const minFps = Math.max(format.minFps, 20)
  const maxFps = Math.min(format.maxFps, 30)

  return (
    <Camera
      {...props}
      fps={[minFps, maxFps]}
    />
  )
}
```

### Other Props

Other props that depend on the `format`:

* `videoHdr`: Enables HDR video capture and preview
* `photoHdr`: Enables HDR photo capture
* `videoStabilizationMode`: Specifies the video stabilization mode to use for the video pipeline


<br />

#### 🚀 Next section: [Preview](./preview)
